package org.hawk.gwt.ppc.introspection.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.hawk.gwt.ppc.introspection.JavaArrayTypeScope;
import org.hawk.gwt.ppc.introspection.JavaConstructor;
import org.hawk.gwt.ppc.introspection.JavaField;
import org.hawk.gwt.ppc.introspection.JavaMethod;
import org.hawk.gwt.ppc.introspection.JavaTypeScope;
import org.hawk.gwt.ppc.introspection.JavaTypeVariable;

/**
 * Scope for non-generic array types.
 * 
 * @author alex.bereznevatiy@gmail.com
 */
final class JavaArrayTypeScopeImpl extends AbstractJavaTypeScope implements JavaArrayTypeScope {
	private JavaTypeScope element;

	JavaArrayTypeScopeImpl(JavaTypeScope element) {
		super(element.getName() + "[]", Object.class.getName(), new ArrayList<String>());
		this.element = element;
	}

	/*
	 * (non-Javadoc)
	 * @see org.hawk.gwt.ppc.introspection.JavaTypeScope#isInterface()
	 */
	public boolean isInterface() {
		return false;
	}

	/*
	 * (non-Javadoc)
	 * @see org.hawk.gwt.ppc.introspection.JavaTypeScope#isClass()
	 */
	public boolean isClass() {
		return false;
	}

	/*
	 * (non-Javadoc)
	 * @see org.hawk.gwt.ppc.introspection.JavaTypeScope#isEnum()
	 */
	public boolean isEnum() {
		return false;
	}

	/*
	 * (non-Javadoc)
	 * @see org.hawk.gwt.ppc.introspection.JavaTypeScope#isAnnotation()
	 */
	public boolean isAnnotation() {
		return false;
	}

	/*
	 * (non-Javadoc)
	 * @see org.hawk.gwt.ppc.introspection.JavaTypeScope#getConstructors()
	 */
	public List<JavaConstructor> getConstructors() {
		return Collections.emptyList();
	}

	/*
	 * (non-Javadoc)
	 * @see org.hawk.gwt.ppc.introspection.JavaTypeScope#getMethods()
	 */
	public List<JavaMethod> getMethods() {
		return Collections.emptyList();
	}

	/*
	 * (non-Javadoc)
	 * @see org.hawk.gwt.ppc.introspection.JavaTypeScope#getFields()
	 */
	public List<JavaField> getFields() {
		return Collections.singletonList(
				(JavaField) new JavaFieldImpl("length", "int", this));
	}

	/*
	 * (non-Javadoc)
	 * @see org.hawk.gwt.ppc.introspection.JavaTypeScope#getField(java.lang.String)
	 */
	JavaField getDeclaredField(String name) {
		if(!name.equals("length")){
			return getSuperClass().getField(name);
		}
		return getFields().get(0);
	}

	/*
	 * (non-Javadoc)
	 * @see org.hawk.gwt.ppc.introspection.JavaTypeScope#getDeclaredClasses()
	 */
	public List<JavaTypeScope> getDeclaredClasses() {
		return Collections.emptyList();
	}

	/*
	 * (non-Javadoc)
	 * @see org.hawk.gwt.ppc.introspection.JavaTypeScope#isPrimitive()
	 */
	public boolean isPrimitive() {
		return false;
	}

	/*
	 * (non-Javadoc)
	 * @see org.hawk.gwt.ppc.introspection.JavaTypeScope#isPrimitiveWrapper()
	 */
	public boolean isPrimitiveWrapper() {
		return false;
	}

	/*
	 * (non-Javadoc)
	 * @see org.hawk.gwt.ppc.introspection.JavaParameterizable#getTypeVariables()
	 */
	public List<JavaTypeVariable> getTypeVariables() {
		return Collections.emptyList();
	}

	/*
	 * (non-Javadoc)
	 * @see org.hawk.gwt.ppc.introspection.JavaArrayTypeScope#getComponentType()
	 */
	public JavaTypeScope getComponentType() {
		return element;
	}

	/* (non-Javadoc)
	 * @see org.hawk.gwt.ppc.introspection.impl.AbstractJavaTypeScope#toString()
	 */
	@Override
	public String toString() {
		return element.toString() + "[]";
	}

	/*
	 * (non-Javadoc)
	 * @see org.hawk.gwt.ppc.introspection.JavaTypeScope#isAssignableFrom(org.hawk.gwt.ppc.introspection.JavaTypeScope)
	 */
	public boolean isAssignableFrom(JavaTypeScope from) {
		if (equals(from)) {
			return true;
		}
		if (from instanceof JavaArrayTypeScope) {
			return getComponentType().isAssignableFrom(((JavaArrayTypeScope)from).getComponentType());
		}
		return false;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (obj == null) {
			return false;
		}
		if (obj == this) {
			return true;
		}
		if (obj instanceof JavaArrayTypeScope) {
			return getComponentType().equals(((JavaArrayTypeScope)obj).getComponentType());
		}
		
		return false;
	}
}
